package com.hmy.infrastructure.service.signature.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.fasc.open.api.bean.base.BaseRes;
import com.fasc.open.api.bean.common.Actor;
import com.fasc.open.api.bean.common.FieldPosition;
import com.fasc.open.api.bean.common.TemplateField;
import com.fasc.open.api.exception.ApiException;
import com.fasc.open.api.v5_1.req.doc.FddFileUrl;
import com.fasc.open.api.v5_1.req.doc.FileProcessReq;
import com.fasc.open.api.v5_1.req.doc.GetUploadUrlReq;
import com.fasc.open.api.v5_1.req.doc.UploadFileByUrlReq;
import com.fasc.open.api.v5_1.req.signtask.*;
import com.fasc.open.api.v5_1.req.template.DocTemplateFillValuesReq;
import com.fasc.open.api.v5_1.req.template.SignTemplateDetailReq;
import com.fasc.open.api.v5_1.res.doc.FileProcessRes;
import com.fasc.open.api.v5_1.res.doc.GetUploadUrlRes;
import com.fasc.open.api.v5_1.res.doc.UploadFileByUrlRes;
import com.fasc.open.api.v5_1.res.signtask.CreateSignTaskRes;
import com.fasc.open.api.v5_1.res.signtask.OwnerDownloadUrlRes;
import com.fasc.open.api.v5_1.res.signtask.SignTaskActorGetUrlRes;
import com.fasc.open.api.v5_1.res.template.DocTemplateFillValuesRes;
import com.fasc.open.api.v5_1.res.template.DocumentInfo;
import com.fasc.open.api.v5_1.res.template.SignTemplateDetailRes;
import com.hmy.ccp.error.exception.HMYRuntimeException;
import com.hmy.infrastructure.api.bo.request.signature.GetUploadUrlApiRequest;
import com.hmy.infrastructure.api.bo.response.signature.GetUploadUrlApiResponse;
import com.hmy.infrastructure.bo.request.signature.*;
import com.hmy.infrastructure.bo.response.signature.*;
import com.hmy.infrastructure.common.constant.InfrastructureConstant;
import com.hmy.infrastructure.service.signature.ISignatureService;
import com.hmy.infrastructure.service.signature.dto.ActorDetailDto;
import com.hmy.infrastructure.service.signature.dto.ContractFileDto;
import com.hmy.infrastructure.service.signature.dto.CreateContractByFileDto;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.weaver.ast.Var;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @Description 电子签约类接口，法大大集成商的实现
 * 所有接口调用前，需要先获取token，再将token放入入参对象中的accessToken属性中
 * @Author seven.qi
 * @Date 2023/11/24 10:04
 * @Version 1.0
 */
@Service("fadadaSignatureService")
@Slf4j
public class FadadaSignatureService extends FadadaBaseSignatureService implements ISignatureService {


    @Override
    public GetUploadUrlApiResponse getUploadFileUrl(GetUploadUrlApiRequest getUploadUrlRequest) throws Exception {
        GetUploadUrlReq getUploadUrlReq = new GetUploadUrlReq();
        BeanUtil.copyProperties(getUploadUrlRequest, getUploadUrlReq);
        // 必须setAccessToken
        getUploadUrlReq.setAccessToken(getToken());
        BaseRes<GetUploadUrlRes> uploadFileUrl = getDocClient().getUploadFileUrl(getUploadUrlReq);
        GetUploadUrlApiResponse getUploadUrlResponse = new GetUploadUrlApiResponse();
        BeanUtil.copyProperties(uploadFileUrl.getData(), getUploadUrlResponse);
        return getUploadUrlResponse;
    }

    @Override
    public CreateSignatureProcessResponse create(CreateSignatureProcessRequest createSignatureProcessRequest) {
        CreateWithTemplateReq createWithTemplateReq = new CreateWithTemplateReq();
        BaseRes<CreateSignTaskRes> withTemplate = null;
        try {
            createWithTemplateReq.setAccessToken(getToken());
            createWithTemplateReq.setSignTemplateId(createSignatureProcessRequest.getSignTemplateId());
            createWithTemplateReq.setAutoStart(Boolean.FALSE);
            createWithTemplateReq.setAutoFillFinalize(Boolean.TRUE);
            createWithTemplateReq.setSignTaskSubject(createSignatureProcessRequest.getTaskSubject());
            createWithTemplateReq.setInitiator(getOpenId());
            createWithTemplateReq.setBusinessId(createSignatureProcessRequest.getBusinessId());
            createWithTemplateReq.setActors(generateActors(createSignatureProcessRequest));
            createWithTemplateReq.setTransReferenceId(createSignatureProcessRequest.getTransReferenceId());
            log.info("request fadada params : {}", JSONUtil.toJsonPrettyStr(createWithTemplateReq));
            withTemplate = getSignTaskClient().createWithTemplate(createWithTemplateReq);
            log.info("request fadada response : {}", JSONUtil.toJsonPrettyStr(withTemplate));
        } catch (ApiException e) {
            log.error("request fadada exception", e);
            throw new HMYRuntimeException(404000003, e.getMessage());
        }
        if (!withTemplate.isSuccess()) {
            throw new HMYRuntimeException(404000011, withTemplate.getMsg());
        }
        CreateSignatureProcessResponse createSignatureProcessResponse = new CreateSignatureProcessResponse();
        createSignatureProcessResponse.setSuccess(Boolean.TRUE);
        createSignatureProcessResponse.setSignTaskId(withTemplate.getData().getSignTaskId());
        return createSignatureProcessResponse;
    }

    @Override
    public CreateContractResponse createContract(CreateContractRequest createContractRequest) {
        CreateWithTemplateReq createWithTemplateReq = new CreateWithTemplateReq();
        BaseRes<CreateSignTaskRes> withTemplate = null;
        try {
            createWithTemplateReq.setAccessToken(getToken());
            createWithTemplateReq.setSignTemplateId(createContractRequest.getSignTemplateId());
            createWithTemplateReq.setAutoStart(Boolean.FALSE);
            createWithTemplateReq.setAutoFillFinalize(Boolean.TRUE);
            createWithTemplateReq.setSignTaskSubject(createContractRequest.getTaskSubject());
            createWithTemplateReq.setInitiator(getOpenId());
            createWithTemplateReq.setBusinessId(createContractRequest.getBusinessId());
            createWithTemplateReq.setActors(generateActors(createContractRequest));
            createWithTemplateReq.setTransReferenceId(createContractRequest.getTransReferenceId());
            log.info("request fadada params : {}", JSONUtil.toJsonPrettyStr(createWithTemplateReq));
            withTemplate = getSignTaskClient().createWithTemplate(createWithTemplateReq);
            log.info("request fadada response : {}", JSONUtil.toJsonPrettyStr(withTemplate));
        } catch (ApiException e) {
            log.error("request fadada exception", e);
            throw new HMYRuntimeException(404000003, e.getMessage());
        }
        if (!withTemplate.isSuccess()) {
            throw new HMYRuntimeException(404000011, withTemplate.getMsg());
        }
        CreateContractResponse createContractResponse = new CreateContractResponse();
        createContractResponse.setSuccess(Boolean.TRUE);
        createContractResponse.setSignTaskId(withTemplate.getData().getSignTaskId());
        return createContractResponse;
    }

    @Override
    public CreateContractByFileResponse createContractByFile(CreateContractByFileRequest createContractRequest) {
        CreateContractByFileDto dto = BeanUtil.copyProperties(createContractRequest, CreateContractByFileDto.class);
        CreateSignTaskReq req = new CreateSignTaskReq();
        BaseRes<CreateSignTaskRes> res = null;
        try {
            uploadAndProcessFile(dto.getContractFileList());
            req.setAccessToken(getToken());
            req.setActors(generateActors(dto));
            req.setDocs(addDocs(dto));
            req.setSignConfigInfo(addDocSignConfigInfo());
            req.setInitiator(getOpenId());
            req.setTransReferenceId(createContractRequest.getTransReferenceId());
            req.setAutoStart(Boolean.FALSE);
            req.setAutoFillFinalize(Boolean.TRUE);
            req.setSignTaskSubject(dto.getTaskSubject());
            req.setBusinessId(dto.getBusinessId());
            req.setTransReferenceId(createContractRequest.getTransReferenceId());
            log.info("request fadada params : {}", JSONUtil.toJsonPrettyStr(req));
            res = getSignTaskClient().create(req);
            log.info("request fadada response : {}", JSONUtil.toJsonPrettyStr(res));
        } catch (Exception e) {
            log.error("request fadada exception", e);
            throw new HMYRuntimeException(404000003, e.getMessage());
        }
        if (!res.isSuccess()) {
            throw new HMYRuntimeException(404000003, res.getMsg());
        }
        CreateContractByFileResponse response = new CreateContractByFileResponse();
        response.setSignTaskId(res.getData().getSignTaskId());
        response.setSuccess(Boolean.TRUE);
        return response;
    }

    private DocSignConfigInfoReq addDocSignConfigInfo() {
        DocSignConfigInfoReq docSignConfigInfoReq = new DocSignConfigInfoReq();
        docSignConfigInfoReq.setRequestVerifyFree(Boolean.TRUE);
        return docSignConfigInfoReq;
    }

    private AddSignConfigInfo addSignConfigInfo() {
        AddSignConfigInfo docSignConfigInfoReq = new AddSignConfigInfo();
        docSignConfigInfoReq.setRequestVerifyFree(Boolean.TRUE);
        return docSignConfigInfoReq;
    }

    private List<AddDocInfo> addDocs(CreateContractByFileDto dto) {
        List<AddDocInfo> addDocInfoList = new ArrayList<>();
        int i = 0;
        for (ContractFileDto contractFile : dto.getContractFileList()) {
            AddDocInfo addDocInfo = new AddDocInfo();
            addDocInfo.setDocName(contractFile.getFileName());
            addDocInfo.setDocFileId(contractFile.getFadadaFileId());
            addDocInfo.setDocId(String.valueOf(i));
            addDocInfo.setDocFields(addDocFields(dto));
            addDocInfoList.add(addDocInfo);
            i++;
        }
        return addDocInfoList;
    }

    private List<com.fasc.open.api.bean.common.Field> addDocFields(CreateContractByFileDto dto) {
        List<com.fasc.open.api.bean.common.Field> fieldList = new ArrayList<>();
        dto.getContractFileList().forEach(contractFile -> {
            // 遍历dto中的actorDetailList，将每个actorDetailList中的fileFieldList添加到fieldList中
            dto.getActorDetailList().forEach(actorDetail -> {
                actorDetail.getActorSignFieldList().forEach(fileField -> {
                    com.fasc.open.api.bean.common.Field field = new com.fasc.open.api.bean.common.Field();
                    field.setFieldId(fileField.getFieldId());
                    field.setFieldName(fileField.getFieldName());
                    field.setFieldType(fileField.getFieldType());
                    field.setPosition(BeanUtil.copyProperties(fileField.getPosition(), FieldPosition.class));
                    fieldList.add(field);
                });
            });
        });


        return fieldList;
    }

    private void uploadAndProcessFile(List<ContractFileDto> contractFileList) throws Exception{
        for (ContractFileDto contractFile : contractFileList) {
            UploadFileByUrlReq uploadFileByUrlReq = new UploadFileByUrlReq();
            uploadFileByUrlReq.setFileType(contractFile.getFileType());
            uploadFileByUrlReq.setFileUrl(contractFile.getFileUrl());
            uploadFileByUrlReq.setAccessToken(getToken());
            BaseRes<UploadFileByUrlRes> uploadFileByUrlResBaseRes = null;
            try {
                uploadFileByUrlResBaseRes = getDocClient().uploadFileByUrl(uploadFileByUrlReq);
            } catch (ApiException e) {
                throw new HMYRuntimeException(404000019, e.getMessage());
            }
            if (!uploadFileByUrlResBaseRes.isSuccess()) {
                throw new HMYRuntimeException(404000019, uploadFileByUrlResBaseRes.getMsg());
            }
            contractFile.setFadadaFileUrl(uploadFileByUrlResBaseRes.getData().getFddFileUrl());
            FileProcessReq fileProcessReq = new FileProcessReq();
            List<FddFileUrl> list = new ArrayList<>();
            FddFileUrl fddFileUrl = new FddFileUrl();
            fddFileUrl.setFileName(contractFile.getFileName());
            fddFileUrl.setFddFileUrl(contractFile.getFadadaFileUrl());
            fddFileUrl.setFileType(contractFile.getFileType());
            list.add(fddFileUrl);
            fileProcessReq.setFddFileUrlList(list);
            fileProcessReq.setAccessToken(getToken());
            BaseRes<FileProcessRes> process = null;
            try {
                process = getDocClient().process(fileProcessReq);
            } catch (ApiException e) {
                throw new HMYRuntimeException(404000020, e.getMessage());
            }
            if (!process.isSuccess()) {
                throw new HMYRuntimeException(404000020, process.getMsg());
            }
            contractFile.setFadadaFileId(process.getData().getFileIdList().get(0).getFileId());
        }
    }

    private List<AddActorsInfo> generateActors(CreateContractByFileDto dto) {
        List<AddActorsInfo> actorList = new ArrayList<>();
        List<ActorDetailDto> actorDetailList = dto.getActorDetailList();
        List<ContractFileDto> contractFileList = dto.getContractFileList();
        actorDetailList.forEach(actorDetail -> {
            AddActorsInfo addActorsInfo = new AddActorsInfo();
            Actor actor = new Actor();
            actor.setActorId(actorDetail.getActorId());
            actor.setActorType(actorDetail.getActorType());
            actor.setActorName(actorDetail.getActorName());
            actor.setPermissions(actorDetail.getPermissions());
            actor.setNotifyAddress(actorDetail.getNotifyAddress());
            actor.setSendNotification(actorDetail.getSendNotification());
            actor.setNotifyType(actorDetail.getNotifyType());
            actor.setAccountName(actorDetail.getAccountName());
            actor.setCertNoForMatch(actorDetail.getCertNoForMatch());
            if (InfrastructureConstant.CORP.equalsIgnoreCase(actorDetail.getActorType())) {
                actor.setActorOpenId(getOpenCorpId());
                // 企业签署方免验证签设置为true
                addActorsInfo.setSignConfigInfo(addSignConfigInfo());
            }
            addActorsInfo.setSignFields(addSignFields(actorDetail, contractFileList));

            addActorsInfo.setActor(actor);
            actorList.add(addActorsInfo);

        });
        return actorList;
    }

    private List<AddSignFieldInfo> addSignFields(ActorDetailDto actorDetail, List<ContractFileDto> contractFileList) {
        List<AddSignFieldInfo> addSignFieldInfoList = new ArrayList<>();
        actorDetail.getActorSignFieldList().forEach(fileField -> {
            AddSignFieldInfo addSignFieldInfo = new AddSignFieldInfo();
            addSignFieldInfo.setFieldId(fileField.getFieldId());
            addSignFieldInfo.setFieldDocId(fileField.getFieldDocId());
            if (Objects.nonNull(actorDetail.getCreateContractSignConfig()) && StrUtil.isNotEmpty(actorDetail.getCreateContractSignConfig().getSealId())) {
                addSignFieldInfo.setSealId(Long.parseLong(actorDetail.getCreateContractSignConfig().getSealId()));
            }
            addSignFieldInfoList.add(addSignFieldInfo);
        });
        return addSignFieldInfoList;
    }

    private List<AddActorsTempInfo> generateActors(CreateContractRequest createContractRequest) {
        List<AddActorsTempInfo> actorList = new ArrayList<>();
        List<ActorDetailRequest> actorDetailList = createContractRequest.getActorDetailList();
        actorDetailList.forEach(actorDetail -> {
            if (InfrastructureConstant.CORP.equalsIgnoreCase(actorDetail.getActorType())) {
                actorList.add(addCorpActor(actorDetail, createContractRequest.getSignTemplateId()));
            } else {
                actorList.add(addPersonActor(actorDetail, createContractRequest.getSignTemplateId()));
            }
        });
        return actorList;
    }


    private AddActorsTempInfo addPersonActor(ActorDetailRequest actorDetail, String signTemplateId) {
        AddActorsTempInfo addActorsTempInfo = new AddActorsTempInfo();
        Actor actor = new Actor();
        actor.setActorId(actorDetail.getActorId());
        actor.setActorType(InfrastructureConstant.PERSON);
        actor.setActorName(actorDetail.getActorName());
        actor.setPermissions(actorDetail.getPermissions());
        actor.setNotifyAddress(actorDetail.getNotifyAddress());
        actor.setSendNotification(actorDetail.getSendNotification());
        actor.setNotifyType(actorDetail.getNotifyType());
        actor.setAccountName(actorDetail.getAccountName());
        actor.setCertNoForMatch(actorDetail.getCertNoForMatch());
        addActorsTempInfo.setActor(actor);
        return addActorsTempInfo;

    }

    private AddActorsTempInfo addCorpActor(ActorDetailRequest actorDetailRequest, String signTemplateId) {
        Actor actor = new Actor();
        actor.setActorId(actorDetailRequest.getActorId());
        actor.setActorType(InfrastructureConstant.CORP);
        actor.setActorName(actorDetailRequest.getActorName());
        actor.setPermissions(actorDetailRequest.getPermissions());
        actor.setActorOpenId(getOpenCorpId());
        actor.setSendNotification(actorDetailRequest.getSendNotification());
        actor.setNotifyAddress(actorDetailRequest.getNotifyAddress());
        actor.setNotifyType(actorDetailRequest.getNotifyType());

        AddActorsTempInfo addActorsTempInfo = new AddActorsTempInfo();
        addActorsTempInfo.setSignConfigInfo(setSignConfigInfo());
        addActorsTempInfo.setSignFields(addSignFields(actorDetailRequest, signTemplateId));
        addActorsTempInfo.setActor(actor);
        return addActorsTempInfo;
    }

    private List<AddSignFieldInfo> addSignFields(ActorDetailRequest actorDetailRequest, String signTemplateId) {
        List<AddSignFieldInfo> addSignFieldInfoList = new ArrayList<>();
        SignTemplateDetailRes signTemplateDetail = getSignTemplateDetail(signTemplateId);
        for (DocumentInfo doc : signTemplateDetail.getDocs()) {
            for (TemplateField docField : doc.getDocFields()) {
                if (InfrastructureConstant.CORP_SEAL.equalsIgnoreCase(docField.getFieldType()) || InfrastructureConstant.CORP_SEAL_CROSS_PAGE.equalsIgnoreCase(docField.getFieldType())) {
                    AddSignFieldInfo addSignFieldInfo = new AddSignFieldInfo();
                    addSignFieldInfo.setFieldId(docField.getFieldId());
                    addSignFieldInfo.setFieldDocId(doc.getDocId().toString());
                    addSignFieldInfo.setSealId(Long.parseLong(actorDetailRequest.getCreateContractSignConfig().getSealId()));
                    addSignFieldInfoList.add(addSignFieldInfo);
                }
            }
        }
        return addSignFieldInfoList;
    }

    @Override
    public SignTemplateFieldFillResponse signTemplateFieldFill(SignTemplateFieldFillRequest signTemplateFieldFillRequest) {

        BaseRes<Void> res = null;
        try {
            FillFieldValuesReq fillFieldValuesReq = new FillFieldValuesReq();
            fillFieldValuesReq.setAccessToken(getToken());
            fillFieldValuesReq.setSignTaskId(signTemplateFieldFillRequest.getSignTaskId());
            fillFieldValuesReq.setDocFieldValues(fillSignTemplateFieldValue(signTemplateFieldFillRequest));
            log.info("request fadada params : {}", JSONUtil.toJsonPrettyStr(fillFieldValuesReq));
            res = getSignTaskClient().fillFieldValues(fillFieldValuesReq);
            log.info("request fadada response : {}", JSONUtil.toJsonPrettyStr(res));
        } catch (ApiException e) {
            throw new HMYRuntimeException(404000004);
        }

        if (!res.isSuccess()) {
            throw new HMYRuntimeException(404000012, res.getMsg());
        }

        SignTemplateFieldFillResponse signTemplateFieldFillResponse = new SignTemplateFieldFillResponse();
        signTemplateFieldFillResponse.setSuccess(Boolean.TRUE);
        return signTemplateFieldFillResponse;
    }


    @Override
    public FileTemplateFieldFillResponse fileTemplateFieldFill(FileTemplateFieldFillRequest fileTemplateFieldFillRequest) {
        BaseRes<DocTemplateFillValuesRes> docTemplateFillValuesResBaseRes = null;
        try {

            DocTemplateFillValuesReq docTemplateFillValuesReq = new DocTemplateFillValuesReq();

            docTemplateFillValuesReq.setDocTemplateId(fileTemplateFieldFillRequest.getFileTemplateId());
            docTemplateFillValuesReq.setFileName(fileTemplateFieldFillRequest.getFileName());
            docTemplateFillValuesReq.setAccessToken(getToken());
            docTemplateFillValuesReq.setOpenCorpId(getOpenCorpId());
            docTemplateFillValuesReq.setDocFieldValues(fillDocFieldValue(fileTemplateFieldFillRequest));
            log.info("request fadada params : {}", JSONUtil.toJsonPrettyStr(docTemplateFillValuesReq));
            docTemplateFillValuesResBaseRes = getTemplateClient().docTemplateFillValues(docTemplateFillValuesReq);
            log.info("request fadada params : {}", JSONUtil.toJsonPrettyStr(docTemplateFillValuesResBaseRes));
        } catch (ApiException e) {
            throw new HMYRuntimeException(404000005);
        }

        if (!docTemplateFillValuesResBaseRes.isSuccess()) {
            throw new HMYRuntimeException(404000014, docTemplateFillValuesResBaseRes.getMsg());
        }

        DocTemplateFillValuesRes docTemplateFillValuesRes = docTemplateFillValuesResBaseRes.getData();

        FileTemplateFieldFillResponse fileTemplateFieldFillResponse = new FileTemplateFieldFillResponse();
        fileTemplateFieldFillResponse.setFileUrl(docTemplateFillValuesRes.getFileDownloadUrl());
        return fileTemplateFieldFillResponse;
    }


    @Override
    public StartSignatureProcessResponse start(StartSignatureProcessRequest startSignatureProcessRequest) {
        BaseRes<Void> start = null;
        try {
            SignTaskBaseReq signTaskBaseReq = new SignTaskBaseReq();
            signTaskBaseReq.setAccessToken(getToken());
            signTaskBaseReq.setSignTaskId(startSignatureProcessRequest.getSignTaskId());
            log.info("request fadada params : {}", JSONUtil.toJsonPrettyStr(startSignatureProcessRequest));
            start = getSignTaskClient().start(signTaskBaseReq);
            log.info("request fadada response : {}", JSONUtil.toJsonPrettyStr(start));
        } catch (ApiException e) {
            log.error("request fadada exception", e);
            throw new HMYRuntimeException(404000006);
        }

        if (!start.isSuccess()) {
            throw new HMYRuntimeException(404000015, start.getMsg());
        }
        StartSignatureProcessResponse startSignatureProcessResponse = new StartSignatureProcessResponse();
        startSignatureProcessResponse.setSuccess(start.isSuccess());
        return startSignatureProcessResponse;
    }

    @Override
    public GetSignFileUrlResponse getSignFileUrl(GetSignFileUrlRequest getSignFileUrlRequest) {
        BaseRes<OwnerDownloadUrlRes> ownerDownloadUrl = null;
        try {
            GetOwnerDownloadUrlReq getOwnerDownloadUrlReq = new GetOwnerDownloadUrlReq();
            getOwnerDownloadUrlReq.setFileType("doc");
            getOwnerDownloadUrlReq.setSignTaskId(getSignFileUrlRequest.getSignTaskId());
            getOwnerDownloadUrlReq.setAccessToken(getToken());
            getOwnerDownloadUrlReq.setOwnerId(getOpenId());
            log.info("request fadada params : {}", JSONUtil.toJsonPrettyStr(getOwnerDownloadUrlReq));
            ownerDownloadUrl = getSignTaskClient().getOwnerDownloadUrl(getOwnerDownloadUrlReq);
            log.info("request fadada response : {}", JSONUtil.toJsonPrettyStr(ownerDownloadUrl));
        } catch (ApiException e) {
            log.error("request fadada exception", e);
            throw new HMYRuntimeException(404000007);
        }

        if (!ownerDownloadUrl.isSuccess()) {
            throw new HMYRuntimeException(404000016, ownerDownloadUrl.getMsg());
        }
        OwnerDownloadUrlRes ownerDownloadUrlRes = ownerDownloadUrl.getData();
        GetSignFileUrlResponse getSignTaskUrlResponse = new GetSignFileUrlResponse();
        getSignTaskUrlResponse.setSignFileUrl(ownerDownloadUrlRes.getDownloadUrl());
        return getSignTaskUrlResponse;
    }

    @Override
    public GetSignTaskUrlResponse getSignTaskUrl(GetSignTaskUrlRequest getSignTaskUrlRequest) {
        BaseRes<SignTaskActorGetUrlRes> signTaskActorGetUrl = null;
        try {
            SignTaskActorGetUrlReq signTaskActorGetUrlReq = new SignTaskActorGetUrlReq();
            if (StrUtil.isEmpty(getSignTaskUrlRequest.getActorId())) {
                signTaskActorGetUrlReq.setActorId(InfrastructureConstant.ACTOR_2);
            } else {
                signTaskActorGetUrlReq.setActorId(getSignTaskUrlRequest.getActorId());
            }
            signTaskActorGetUrlReq.setSignTaskId(getSignTaskUrlRequest.getSignTaskId());
            signTaskActorGetUrlReq.setAccessToken(getToken());
            log.info("request fadada params : {}", JSONUtil.toJsonPrettyStr(signTaskActorGetUrlReq));
            signTaskActorGetUrl = getSignTaskClient().signTaskActorGetUrl(signTaskActorGetUrlReq);
            log.info("request fadada response : {}", JSONUtil.toJsonPrettyStr(signTaskActorGetUrl));
        } catch (ApiException e) {
            log.error("request fadada exception", e);
            throw new HMYRuntimeException(404000008);
        }
        if (!signTaskActorGetUrl.isSuccess()) {
            throw new HMYRuntimeException(404000017, signTaskActorGetUrl.getMsg());
        }
        GetSignTaskUrlResponse getSignTaskUrlResponse = new GetSignTaskUrlResponse();
        getSignTaskUrlResponse.setSignTaskUrl(signTaskActorGetUrl.getData().getActorSignTaskUrl());
        return getSignTaskUrlResponse;
    }

    @Override
    public SignTaskCancelResponse signTaskCancel(SignTaskCancelRequest request) {
        BaseRes<Void> cancel = null;
        try {
            SignTaskCancelReq req = new SignTaskCancelReq();
            req.setAccessToken(getToken());
            req.setSignTaskId(request.getContractTaskId());
            if (StrUtil.isNotEmpty(request.getTerminationNote())) {
                req.setTerminationNote(request.getTerminationNote());
            }
            log.info("request fadada params : {}", JSONUtil.toJsonPrettyStr(req));
            cancel = getSignTaskClient().cancel(req);
            log.info("request fadada response : {}", JSONUtil.toJsonPrettyStr(cancel));
        } catch (ApiException e) {
            log.error("request fadada exception", e);
            throw new HMYRuntimeException(404000008);
        }
        if (!cancel.isSuccess()) {
            throw new HMYRuntimeException(404000017, cancel.getMsg());
        }
        SignTaskCancelResponse response = new SignTaskCancelResponse();
        response.setSuccess(cancel.isSuccess());
        return response;
    }

    private SignTemplateDetailRes getSignTemplateDetail(String signTemplateId) {
        BaseRes<SignTemplateDetailRes> signTemplateDetail = null;
        try {
            SignTemplateDetailReq signTemplateDetailReq = new SignTemplateDetailReq();
            signTemplateDetailReq.setSignTemplateId(signTemplateId);
            signTemplateDetailReq.setAccessToken(getToken());
            // ownerId必填，不然会找不到对应的数据
            signTemplateDetailReq.setOwnerId(getOpenId());
            signTemplateDetail = getTemplateClient().getSignTemplateDetail(signTemplateDetailReq);
        } catch (ApiException e) {
            throw new HMYRuntimeException(404000009);
        }
        if (!signTemplateDetail.isSuccess()) {
            throw new HMYRuntimeException(404000018, signTemplateDetail.getMsg());
        }
        return signTemplateDetail.getData();
    }

    private List<AddActorsTempInfo> generateActors(CreateSignatureProcessRequest createSignatureProcessRequest) {
        List<AddActorsTempInfo> actorList = new ArrayList<>();
        actorList.add(addCreatorCorp(createSignatureProcessRequest));
        actorList.add(addAuthorizer(createSignatureProcessRequest));
        return actorList;
    }

    private List<DocTemplateFillValuesReq.DocFieldValue> fillDocFieldValue(FileTemplateFieldFillRequest fileTemplateFieldFillRequest) {
        List<DocTemplateFillValuesReq.DocFieldValue> docFieldValueList = new ArrayList<>();
        for (Field field : fileTemplateFieldFillRequest.getFieldList()) {
            DocTemplateFillValuesReq.DocFieldValue docFieldValueInfo = new DocTemplateFillValuesReq.DocFieldValue();
            docFieldValueInfo.setFieldName(field.getKey());
            docFieldValueInfo.setFieldValue(field.getValue());
            docFieldValueList.add(docFieldValueInfo);
        }
        return docFieldValueList;
    }

    private List<DocFieldValueInfo> fillSignTemplateFieldValue(SignTemplateFieldFillRequest signTemplateFieldFillRequest) {

        SignTemplateDetailRes signTemplateDetail = getSignTemplateDetail(signTemplateFieldFillRequest.getSignTemplateId());

        List<DocFieldValueInfo> docFieldValueInfos = new ArrayList<>();

        for (DocumentInfo doc : signTemplateDetail.getDocs()) {
            for (Field field : signTemplateFieldFillRequest.getFieldList()) {
                DocFieldValueInfo docFieldValueInfo = new DocFieldValueInfo();
                docFieldValueInfo.setDocId(doc.getDocId().toString());
                docFieldValueInfo.setFieldName(field.getKey());
                docFieldValueInfo.setFieldValue(field.getValue());
                docFieldValueInfos.add(docFieldValueInfo);
            }
        }
        return docFieldValueInfos;
    }

    private AddActorsTempInfo addAuthorizer(CreateSignatureProcessRequest createSignatureProcessRequest) {
        AddActorsTempInfo authorizer = new AddActorsTempInfo();
        Actor actor = new Actor();
        actor.setActorId(InfrastructureConstant.ACTOR_2);
        actor.setActorType(InfrastructureConstant.PERSON);
        actor.setActorName(createSignatureProcessRequest.getAuthorizerInfoList().get(0).getName());
        actor.setPermissions(addPermissionList());
        actor.setNotifyAddress(createSignatureProcessRequest.getAuthorizerInfoList().get(0).getPhone());
        actor.setAccountName(createSignatureProcessRequest.getAuthorizerInfoList().get(0).getPhone());
        actor.setCertNoForMatch(createSignatureProcessRequest.getAuthorizerInfoList().get(0).getIdCardNo());
        actor.setSendNotification(Boolean.TRUE);
        actor.setNotifyType(addNotifyType());
        authorizer.setActor(actor);
        return authorizer;
    }

    private AddActorsTempInfo addCreatorCorp(CreateSignatureProcessRequest createSignatureProcessRequest) {
        Actor actor = new Actor();
        actor.setActorId(InfrastructureConstant.ACTOR_1);
        actor.setActorType(InfrastructureConstant.CORP);
        actor.setActorName(getCorpName());
        actor.setPermissions(addPermissionList());
        actor.setActorOpenId(getOpenCorpId());
        actor.setSendNotification(Boolean.FALSE);
        actor.setNotifyAddress(createSignatureProcessRequest.getCreatorPhone());
        actor.setNotifyType(addNotifyType());

        AddActorsTempInfo addActorsTempInfo = new AddActorsTempInfo();
        addActorsTempInfo.setSignConfigInfo(setSignConfigInfo());
        addActorsTempInfo.setSignFields(setSignFieldInfo(createSignatureProcessRequest));
        addActorsTempInfo.setActor(actor);
        return addActorsTempInfo;
    }

    private List<AddSignFieldInfo> setSignFieldInfo(CreateSignatureProcessRequest createSignatureProcessRequest) {
        List<AddSignFieldInfo> addSignFieldInfoList = new ArrayList<>();
        String signTemplateId = createSignatureProcessRequest.getSignTemplateId();
        SignTemplateDetailRes signTemplateDetail = getSignTemplateDetail(signTemplateId);
        for (DocumentInfo doc : signTemplateDetail.getDocs()) {
            for (TemplateField docField : doc.getDocFields()) {
                if (InfrastructureConstant.CORP_SEAL.equalsIgnoreCase(docField.getFieldType()) || InfrastructureConstant.CORP_SEAL_CROSS_PAGE.equalsIgnoreCase(docField.getFieldType())) {
                    AddSignFieldInfo addSignFieldInfo = new AddSignFieldInfo();
                    addSignFieldInfo.setFieldId(docField.getFieldId());
                    addSignFieldInfo.setFieldDocId(doc.getDocId().toString());
                    addSignFieldInfo.setSealId(Long.parseLong(createSignatureProcessRequest.getSealId()));
                    addSignFieldInfoList.add(addSignFieldInfo);
                }
            }
        }
        return addSignFieldInfoList;
    }

    private List<String> addPermissionList() {
        List<String> permissionList = new ArrayList<>();
//        permissionList.add(InfrastructureConstant.FADADA_PERMISSION_FILL);
        permissionList.add(InfrastructureConstant.FADADA_PERMISSION_SIGN);
        return permissionList;
    }

    private List<String> addNotifyType() {
        List<String> notifyType = new ArrayList<>();
        notifyType.add(InfrastructureConstant.FADADA_NOTIFY_TYPE_START);
        notifyType.add(InfrastructureConstant.FADADA_NOTIFY_TYPE_FINISH);
        return notifyType;
    }


    private TemplateSignConfigInfoReq setSignConfigInfo() {
        TemplateSignConfigInfoReq templateSignConfigInfoReq = new TemplateSignConfigInfoReq();
        templateSignConfigInfoReq.setRequestVerifyFree(Boolean.TRUE);
        return templateSignConfigInfoReq;
    }

}
